/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.cef.core.valuegetter;

import com.inspur.edp.cef.api.ICefValueGetter;
import com.inspur.edp.cef.api.ValueGetterConfig;
import com.inspur.edp.cef.api.exceptions.ErrorCodes;
import com.inspur.edp.cef.api.message.CefException;
import com.inspur.edp.cef.entity.entity.ICefData;
import com.inspur.edp.cef.spi.entity.IAuthFieldValue;
import com.inspur.edp.udt.entity.ISimpleUdtData;
import com.inspur.edp.udt.entity.IUdtData;
import io.iec.edp.caf.commons.exception.CAFRuntimeException;
import io.iec.edp.caf.commons.exception.ExceptionLevel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.InvocationTargetException;

/**
 * @author Jakeem
 * @Data 2019/12/27 - 10:03
 */
//@Configuration("com.inspur.dep.cef.api.dataType.entity.CefValueGetter")
public
class CefValueGetter implements ICefValueGetter {
    @Override
    public
    Object getValue(ICefData data, String path, ValueGetterConfig config) {
        if (data == null || path == null || path.equals("") || config == null) {
            //格式输入不规范抛出异常
            throw new CefException("当前的输入参数不规范,getValue的输入参数不能为null,请检查。");
        }
        String str[] = null;
        if (path.contains(".")) {
            str = path.split("[.]");
        }
        if (!path.contains(".")) {
            str = new String[1];
            str[0] = path;
        }

        Object befField = data.getValue(str[0]);
        return getFinalValue(str, befField, config, 1);
    }

    protected
    Object getFinalValue(String[] pathNames, Object field, ValueGetterConfig config, int namesCount) {
        Object returnField = null;
        if (namesCount >= pathNames.length) {
            if (config.getSingleValueUdt() == true && field instanceof ISimpleUdtData){
                if(field == null){
                    return null;
                }
                field  = ((ISimpleUdtData) field).getValue();
            }
            if(config.getAssociationValue() == true && field instanceof IAuthFieldValue){
                field =  ((IAuthFieldValue)field).getValue();
            }
            return field;
        }
        //判断的当前是否是单值UDT
        if (field instanceof ISimpleUdtData) {
            Object comField = ((ISimpleUdtData) field).getValue();
            if(config.getSingleValueUdt() == false){
                ++namesCount;
            }
            if(comField == null){
                return null;
            }
            returnField = getFinalValue(pathNames, comField, config, namesCount);
        }else if (field instanceof ICefData) {
            //当前是动态BE或者多值udt
            Object comField = ((ICefData) field).getValue(pathNames[namesCount]);
            returnField = getFinalValue(pathNames, comField, config, ++namesCount);
        } else if (field instanceof IAuthFieldValue) {
                //判断当前是否是关联
                try {
                    String getNextMethod = "get" + pathNames[namesCount];
                    Object comField = field.getClass().getMethod(getNextMethod).invoke(field);

                    returnField = getFinalValue(pathNames, comField, config, ++namesCount);
                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    throw new CAFRuntimeException("", ErrorCodes.Scope_JavaReflectionException, "当前关联字段反射失败，字段：" + pathNames[namesCount], null, ExceptionLevel.Error, true);
                }
            }
        //当前取出来不是上述字段类型，并且没有取到最终，并且不为Null(没有赋值)
//        if (returnField != null && namesCount < pathNames.length) {
//            throw new CAFRuntimeException("", ErrorCodes.Scope_JavaReflectionException, "当前字段getValue()异常，字段：" + pathNames[namesCount]+"请检查", null, ExceptionLevel.Error, true);
//        }
        return returnField;
    }
}
